﻿#ifndef __AF_GRAPHICS_H__
#define __AF_GRAPHICS_H__

#include "AF_Define.h"

namespace AF
{
	typedef int Anchor;
	class Graphics; //-* ForEach
}
typedef AF::Anchor			AF_DAnchor;
typedef AF::Graphics			AF_CGraphics;

namespace AF
{
	/// 锚点
	enum AnchorType
	{
		/// 顶部
		ANCHOR_TOP		= 0x00,
		///  垂直居中
		ANCHOR_VCENTER		= 0x10,
		/// 底部
		ANCHOR_BUTTON		= 0x30,
		/// 垂直掩码
		ANCHOR_VMARK		= 0xF0,

		/// 左面
		ANCHOR_LEFT		= 0x00,
		/// 水平居中
		ANCHOR_HCENTER		= 0x01,
		/// 右面
		ANCHOR_RIGHT		= 0x03,
		/// 水平掩码
		ANCHOR_HMARK		= 0x0F,
	};
}
typedef AF::AnchorType			AF_EAnchorType;
#define AF_ANCHOR_TOP			AF::ANCHOR_TOP
#define AF_ANCHOR_VCENTER		AF::ANCHOR_VCENTER
#define AF_ANCHOR_BUTTON		AF::ANCHOR_BUTTON
#define AF_ANCHOR_VMARK			AF::ANCHOR_VMARK
#define AF_ANCHOR_LEFT			AF::ANCHOR_LEFT
#define AF_ANCHOR_HCENTER		AF::ANCHOR_HCENTER
#define AF_ANCHOR_RIGHT			AF::ANCHOR_RIGHT
#define AF_ANCHOR_HMARK			AF::ANCHOR_HMARK

namespace AF
{
	/// 穿越屏幕
	enum ThroughType
	{
		/// 无穿越
		THROUGH_NONE,
		/// 垂直穿越
		THROUGH_VERTICAL,
		/// 水平穿越
		THROUGH_HORIZONTAL,
		/// 都穿越
		THROUGH_BOTH
	};				
}
typedef AF::ThroughType			AF_EThroughType;
#define AF_THROUGH_NONE			AF::THROUGH_NONE
#define AF_THROUGH_VERTICAL		AF::THROUGH_VERTICAL
#define AF_THROUGH_HORIZONTAL		AF::THROUGH_HORIZONTAL
#define AF_THROUGH_BOTH			AF::THROUGH_BOTH
					
namespace AF
{
	/// 可绘制对象类型
	enum GraphicsType
	{
		/// 未知绘制元素
		GRAPHICS_UNKNOW,
		/// 图像元素
		GRAPHICS_IMAGE,
		/// 标签元素
		GRAPHICS_LABEL,
		/// 特效元素
		GRAPHICS_EFFECT,
		/// 模型元素
		GRAPHICS_MODEL,
		/// 界面元素
		GRAPHICS_FACE,
		/// 其他元素
		GRAPHICS_OTHER
	};
}
typedef AF::GraphicsType		AF_EGraphicsType;
#define AF_GRAPHICS_UNKNOW		AF::GRAPHICS_UNKNOW
#define AF_GRAPHICS_IMAGE		AF::GRAPHICS_IMAGE
#define AF_GRAPHICS_LABEL		AF::GRAPHICS_LABEL
#define AF_GRAPHICS_EFFECT		AF::GRAPHICS_EFFECT
#define AF_GRAPHICS_MODEL		AF::GRAPHICS_MODEL
#define AF_GRAPHICS_FACE		AF::GRAPHICS_FACE
#define AF_GRAPHICS_OTHER		AF::GRAPHICS_OTHER


#include "AF_Bundle.h"
#include "AF_Render.h"
#include "AF_Action.h"
#include "AF_ForEach.h"


/// 默认缩放值
#define AF_ZOOM_DEFAULT			1.0f
/// 默认旋转值
#define AF_ANGLE_DEFAULT		0.0f

namespace AF
{
	/// 可绘制对象基类
	class _ABSTRACT Graphics : public ForEach
	{
	protected:
		/// 没有渲染
		static NotRender	m_NothingRender;

	private:
		static UINT		GetID();
		static UINT		m_nID;

	public:
		Graphics();
		virtual ~Graphics();


		/**
		 *  @name 属性成员
		 */
	public:
		/// 名字属性，用于布局管理
		DIM_ATTRIB_R(_STRING, GraphicsName);
		/// 可见属性
		DIM_ATTRIB(bool, Visible);		// 可见性
		/// 位置属性
		DIM_ATTRIB(Point, Location);		// 相对位置(非屏幕位置)
		/// 穿屏属性
		DIM_ATTRIB(ThroughType, Through);	// 穿越屏幕
		/// 尺寸属性
		DIM_ATTRIB(Size, Size);			// 尺寸
		/// 锚点属性
		DIM_ATTRIB(Anchor, Anchor);		// 锚点相对位置
		/// 锚点偏移属性
		DIM_ATTRIB(Point, AnchorOffset);	// 锚点偏移坐标
		/// 透明度属性
		DIM_ATTRIB(BYTE, Alpha);		// 透明度(0 - 255)
		/// 旋转属性
		DIM_ATTRIB(double, Angle);		// 旋转(0 - 360)
		/// 缩放属性
		DIM_ATTRIB(double, Zoom);		// 缩放(0 - 1)


		/**
		 *  @name 事件成员
		 */
		// 定义事件
	public:
		/// 渲染之前
		virtual bool		OnPreRender(Graphics* pGraphics);	// 渲染之前
		/// 渲染时
		virtual bool		OnRender()				// 渲染时
					{return m_pRender->Render(this);}


		/**
		 *  @name 停靠功能成员
		 */
	public:
		virtual Pointer		Foreach(bool isFirst)
					{return NULL;}
		virtual UINT		GetCount()
					{return 0;}

		/// 停靠到指定的元素组中
		void			DockGroup(Graphics* pgGroup);
		/// 获得父对象组的指针
		Graphics*		GetDockGroup();

		/// 忽略尺寸
		// 此对象的父级界面中，在需要计算界面尺寸时，忽略次对象的尺寸。
		void			IgnoreSize();
		bool			IsIgnoreSize();

	protected:
		/// 父对象组指针
		Graphics*		m_pgGroup;
		/// 忽略尺寸计算
		bool			m_isIgnoreSize;


		/**
		 *  @name 动作功能成员
		 */
	private:
		struct ActionNode
		{
			bool		isCreate;
			Action*		pAction;
		};
	public:
		/// 添加动作效果
		template<class TAction>
		bool			AddAction(_STRING strActionName, TAction** _OUT ppAction);
		/// 添加动作效果
		bool			AddAction(_STRING strActionName, Action* pAction);
		/// 移除动作效果
		Action*			RemoveAction(_STRING strActionName);

		/// 获得指定名字的动作效果指针
		Action*			GetAction(_STRING strActionName);

		/// 运行动画效果
		void			PlayAction(_STRING strActionName);
		/// 暂停动画效果
		void			PauseAction(_STRING strActionName);
		/// 停止动画效果
		void			StopAction(_STRING strActionName);

	protected:
		/// 动画效果数组
		Table<ActionNode*>	m_tabPActions;



		/**
		 *  @name 其他成员
		 */
	public:
		/// 设置名字，只能设置一次
		void			SetGraphicsName(_STRING strGraphicsName);
		/// 设置隐藏
		void			SetHide(bool isHide = true);
		/// 设置位置
		void			SetLocation(int nX, int nY);
		/// 设置位置
		void			SetLocation(float fX, float fY, Graphics* pgFrame = NULL);
		/// 设置锚点
		void			SetAnchor(int nX, int nY);
		/// 设置锚点
		void			SetAnchor(float fX, float fY);
		/// 设置锚点偏移
		void			SetAnchorOffset(int nX, int nY);
		/// 设置尺寸
		void			SetSize(UINT nWidth, UINT nHeight);
		/// 设置自定义渲染类
		void			SetRender(Renderable* pRender);

		/// 获得可绘制对象类型
		/**
		 * @returns
		 *	返回类型。
		 */
		int			GetGType();
		/// 获得是否隐藏
		bool			GetHide();
		/// 获得最终是否可见
		bool			GetScreenVisible();
		/// 获得最终X轴坐标坐标值
		int			GetScreenPosX();
		/// 获得最终Y轴坐标坐标值
		int			GetScreenPosY();
		/// 获得最终缩放宽度
		int			GetScreenSizeW();
		/// 获得最终缩放高度
		int			GetScreenSizeH();
		/// 获得最终屏幕穿越
		ThroughType		GetScreenThrough();
		/// 获得最终透明值
		BYTE			GetScreenAlpha();
		/// 获得最终旋转值
		double			GetScreenAngle();
		/// 获得最终缩放值
		double			GetScreenZoom();
		/// 附加信息
		Bundle&			Information();

	protected:
		/// 可绘制对象类型
		GraphicsType		m_nGType;
		/// 特殊渲染接口
		Renderable*		m_pRender;
		/// 附加信息
		Bundle			m_Information;
	};

	template<class TAction>
	bool Graphics::AddAction(_STRING strActionName, TAction** _OUT ppAction)
	{
		AF_CHECK_R(strActionName != "", false);

		if(m_tabPActions.Find(strActionName) >= 0)
			return false;

		TAction* _pAction = AF_NEW(TAction);

		ActionNode* _pANode = AF_NEW(ActionNode);
		_pANode->isCreate = false;
		_pANode->pAction = _pAction;
		m_tabPActions.Put(strActionName, _pANode);

		_pAction->SetHostGraphics(this);

		*ppAction = _pAction;

		return true;
	}
}

#endif
